#pragma once
#include<assert.h>
#include<iostream>
using namespace std;
namespace sakura
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		void swap(const T num)
		{
			std::swap(start, num.start);
			std::swap(finish, num.finish);
			std::swap(end_of_storage, num.end_of_storage);

		}
		vector()
		{ }
		vector(const T& num)
		{
			swap(num);
		}
		vector(size_t n, const T& val = T())
		{
			reserve(n);
			for (size_t i = 0; i < n; i++)
			{
				start[i] = val;
			}
		}
		template<class InPutInterator>
		vector(InPutInterator first, InPutInterator last)
		{
			while(first!=last)
			{
				push_back(*first);
				first++;
			}
		}
		vector<T>& operator=(const T& num)
		{
			swap(num);
			return this;
		}
		~vector()
		{
			if (start)
			{
				delete[] start;
				start = finish = end_of_storage = nullptr;
			}
		
		}
		void clear()
		{
			finish = start;
		}
		size_t size()
		{
			return finish - start;
		}
		size_t capacity()
		{
			return end_of_storage - start;
		}
		iterator begin()
		{
			return start;
		}
		iterator end()
		{

			return finish;
 		}
		const_iterator begin() const
		{
			return start;
		}
		const_iterator end() const
		{

			return finish;
		}
		T& operator[](int num)
		{
			assert(num >= 0);
			assert(num < size());
			return start[num];
		}
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				T* ptm = new T[n];
				size_t oldsize = size();
				//memcpy(ptm, start,oldsize*sizeof(T));
				for (size_t i = 0; i < oldsize; i++)
				{
					ptm[i] = start[i];
				}
				delete[] start;
				start = ptm;
				finish = ptm + oldsize;
				end_of_storage = ptm + n;
			}
		}
		void push_back(const T& num)
		{
			if (finish == end_of_storage)
				reserve(capacity() == 0 ? 4 : 2 * capacity());
			*finish = num;
			finish++;
		}
		iterator insert(iterator pos, const T& num)
		{
			if (finish == end_of_storage)
			{
				size_t gap = pos - start;
				reserve(capacity() == 0 ? 4 : 2 * capacity());
				pos = start + gap;
			}
			iterator ptm = finish - 1;
			while (ptm >= pos)
			{
				*(ptm + 1) = *ptm;
				ptm--;
			}
			*pos = num;
			finish++;
			return pos;
		}
		iterator erase(iterator pos)
		{
			assert(pos >= start);
			assert(pos < finish);
			iterator ptm = pos;
			while (ptm < finish)
			{
				*ptm = *(ptm + 1);
				ptm++;
			}
			finish--;
			return pos;
		}
		void pop_back()
		{
			finish--;
		}
		void resize(size_t n, T val= T())
		{
			if (n < size())
			{
				finish = start + n;
			}
			else
			{
				reserve(n);
				while (finish < start + n)
				{
					*finish = val;
					finish++;
				}
			}
		}
	private:
		iterator start=nullptr;
		iterator finish=nullptr;
		iterator end_of_storage=nullptr;
	};
	template<class x>
	void printf_container(const x& v)
	{
		auto it = v.begin();
		while (it != v.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;
		for (auto ch : v)
		{
			cout << ch << " ";
		}
		cout << endl;
	}
}